home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume23 / newsxd / part01 next >
Encoding:
Internet Message Format  |  1990-10-09  |  52.0 KB

  1. Subject:  v23i011:  Netnews transmission daemon, Part01/03
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: ed5379d6 139a46d7 43496c0a 496142d4
  5.  
  6. Submitted-by: Chris Myers <chris@wugate.wustl.edu>
  7. Posting-number: Volume 23, Issue 11
  8. Archive-name: newsxd/part01
  9.  
  10. [  This is used at UUNET; is that becoming the seal of approval for
  11.    Usenet software?  --r$  ]
  12.  
  13. The newsxd program is a configurable daemon for controlling the
  14. transmission of netnews.  It allows the definition of multiple categories
  15. of service, by setting a number of parameters defining things such as how
  16. often news is to be transmitted, the number of news transmitters that can
  17. be active at one time, the maximum time a transmitter may spend sending
  18. netnews to a single host, and the maximum system load at which netnews
  19. transmitters may be started.  newsxd can also be used to start up other
  20. programs which must be restarted upon exit, or which must be run at
  21. regular intervals with greater granularity than cron(8) allows.
  22.  
  23. #! /bin/sh
  24. # This is a shell archive.  Remove anything before this line, then feed it
  25. # into a shell via "sh file" or similar.  To overwrite existing files,
  26. # type "sh file -c".
  27. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  28. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  29. # Contents:  README MANIFEST config.c newsxd.8
  30. # Wrapped by rsalz@litchi.bbn.com on Fri Jul 13 15:03:56 1990
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. echo If this archive is complete, you will see the following message:
  33. echo '          "shar: End of archive 1 (of 3)."'
  34. if test -f 'README' -a "${1}" != "-c" ; then 
  35.   echo shar: Will not clobber existing file \"'README'\"
  36. else
  37.   echo shar: Extracting \"'README'\" \(1385 characters\)
  38.   sed "s/^X//" >'README' <<'END_OF_FILE'
  39. XThe newsxd program is a configurable daemon for controlling the
  40. Xtransmission of netnews.  It allows the definition of multiple
  41. Xcategories of service, by setting a number of parameters defining
  42. Xthings such as how often news is to be transmitted, the number of news
  43. Xtransmitters that can be active at one time, the maximum time a
  44. Xtransmitter may spend sending netnews to a single host, and the maximum
  45. Xsystem load at which netnews transmitters may be started.  newsxd can
  46. Xalso be used to start up other programs which must be restarted upon
  47. Xexit, or which must be run at regular intervals with greater
  48. Xgranularity than cron(8) allows.
  49. X
  50. X                       newsxd Installation
  51. X
  52. XTo compile newsxd, you need to do the following things:
  53. X
  54. X1) Edit newsxd.h, and make any changes necessary to the default
  55. X   locations for the newsxd data files.  Also select whether you want to
  56. X   have newsxd log to syslog or to it's own log file.
  57. X
  58. X2) Edit the Makefile and define the correct locations to store newsxd
  59. X   and it's manpage on your system.
  60. X
  61. X3) make depend
  62. X
  63. X4) make install
  64. X
  65. X5) Create a newsxd.conf file and install it in the appropriate location
  66. X   (the default is /usr/local/etc/newsxd.conf).  Sample configuration files
  67. X   are included as complex.conf and simple.conf.
  68. X
  69. X6) Turn off any nntpxmit's, sendbatch's, etc. so they don't conflict with
  70. X   the ones started by newsxd.
  71. X
  72. X7) Run newsxd
  73. END_OF_FILE
  74.   if test 1385 -ne `wc -c <'README'`; then
  75.     echo shar: \"'README'\" unpacked with wrong size!
  76.   fi
  77.   # end of 'README'
  78. fi
  79. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  80.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  81. else
  82.   echo shar: Extracting \"'MANIFEST'\" \(593 characters\)
  83.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  84. X   File Name        Archive #    Description
  85. X----------------------------------------------------------
  86. XREADME                     1    
  87. XMANIFEST                   1    This shipping list
  88. XMakefile                   3    
  89. Xcomplex.conf               3    
  90. Xconfig.c                   1    
  91. Xdefs.h                     2    
  92. Xlog.c                      3    
  93. Xmain.c                     3    
  94. Xnewsxd.8                   1    
  95. Xnewsxd.conf                3    
  96. Xnewsxd.h                   3    
  97. Xpatchlevel.h               2    
  98. Xprocess.c                  2    
  99. Xsimple.conf                2    
  100. Xutil.c                     2    
  101. Xversion.c                  2    
  102. END_OF_FILE
  103.   if test 593 -ne `wc -c <'MANIFEST'`; then
  104.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  105.   fi
  106.   # end of 'MANIFEST'
  107. fi
  108. if test -f 'config.c' -a "${1}" != "-c" ; then 
  109.   echo shar: Will not clobber existing file \"'config.c'\"
  110. else
  111.   echo shar: Extracting \"'config.c'\" \(28527 characters\)
  112.   sed "s/^X//" >'config.c' <<'END_OF_FILE'
  113. X/*
  114. X * #include <legal/bs.h>
  115. X >
  116. X > Copyright (c) 1989 Washington University in Saint Louis, Missouri and
  117. X > Chris Myers. All rights reserved.
  118. X >
  119. X > Permission is hereby granted to copy, reproduce, redistribute or
  120. X > otherwise use this software as long as: (1) there is no monetary
  121. X > profit gained specifically from the use or reproduction of this
  122. X > software, (2) it is not sold, rented, traded, or otherwise marketed,
  123. X > (3) the above copyright notice and this paragraph is included
  124. X > prominently in any copy made, and (4) that the name of the University
  125. X > is not used to endorse or promote products derived from this software
  126. X > without the specific prior written permission of the University.
  127. X > THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  128. X > IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  129. X > WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  130. X >
  131. X */
  132. X
  133. X#include "defs.h"
  134. X
  135. X/*************************************************************************/
  136. X/* FUNCTION  : getclass                                                  */
  137. X/* PURPOSE   : Return a pointer to the class structure given the name of */
  138. X/*             a class                                                   */
  139. X/* ARGUMENTS : The name of a class                                       */
  140. X/*************************************************************************/
  141. X
  142. Xstruct class *
  143. Xgetclass(classname)
  144. X   char *classname;
  145. X
  146. X{
  147. Xstruct  class   *classptr;
  148. X
  149. X   if (strlen(classname) > MAXCLASSNAMELEN - 1) {
  150. X      Dprintf("(getclass): classname %s is too long, no match\n", classname);
  151. X      return((struct class *) NULL);
  152. X   }
  153. X
  154. X   foreach (classptr, classlist) {
  155. X      Dprintf("(getclass): now checking class %s\n", classptr->classname);
  156. X      if (strcmp(classname, classptr->classname) == 0) break;
  157. X   }
  158. X
  159. X   return(classptr);
  160. X
  161. X}
  162. X
  163. X/*************************************************************************/
  164. X/* FUNCTION  : addclass                                                  */
  165. X/* PURPOSE   : Add a class to or modify a class in the class list        */
  166. X/* ARGUMENTS : All the information needed to define a class...           */
  167. X/*************************************************************************/
  168. X
  169. Xvoid
  170. Xaddclass(classname,maxxmits,interval,startint,maxload,ttl,ttlpenalty,nice,flags,         debugflags)
  171. X   char *classname, *debugflags;
  172. X   int  maxxmits, interval, startint, maxload, ttl, ttlpenalty, nice, flags;
  173. X
  174. X{
  175. Xstruct  class   *classptr = classlist;
  176. Xchar    *flagbuf;
  177. Xint     loop,
  178. X        newclass = 0;
  179. X
  180. X   if (strlen(classname) > MAXCLASSNAMELEN - 1) {
  181. X      logerr("(addclass) Class name %s too long, max %d - ignoring\n",
  182. X         classname, MAXCLASSNAMELEN - 1);
  183. X      return;
  184. X   }
  185. X
  186. X   if ((classptr = getclass(classname)) == NULL) {
  187. X      Dprintf("(addclass): CALLOCing new class structure\n");
  188. X      classptr = (struct class *) calloc(1, sizeof(struct class));
  189. X      if (classptr == NULL) {
  190. X         logerr("(addclass) Can't calloc struct class for class %s\n",
  191. X            classname);
  192. X         return;
  193. X      }
  194. X      for (loop = 0; loop < MAXCLASSXMITTERS; loop++)
  195. X         classptr->slots[loop] = '.';
  196. X      newclass++;
  197. X   } else if (classptr->valid == 1) {
  198. X      logerr("(addclass) Duplicated class %s\n", classname);
  199. X      return;
  200. X   }
  201. X
  202. X   /*
  203. X    * Build class structure for this class and insert at the head of the
  204. X    * class list
  205. X    */
  206. X
  207. X   (void) strcpy(classptr->classname, classname);
  208. X   classptr->maxxmits = maxxmits;
  209. X   classptr->options.maxload = maxload;
  210. X   classptr->options.interval = interval;
  211. X   classptr->options.startint = startint;
  212. X   classptr->options.ttl = ttl;
  213. X   classptr->options.deltanice = nice;
  214. X   classptr->options.ttlpenalty = ttlpenalty;
  215. X   classptr->valid = 1;
  216. X   classptr->xmitsernum = 0;
  217. X   classptr->members = 0;
  218. X   classptr->debugargc = 0;
  219. X
  220. X   if (debug && strlen(debugflags) > 0) {
  221. X      if ((flagbuf = (char *) calloc(1, strlen(debugflags) + 1)) != NULL) {
  222. X         (void) strcpy(flagbuf, debugflags);
  223. X         while (1) {
  224. X            classptr->debugargv[classptr->debugargc++] = flagbuf;
  225. X            if ((flagbuf = STRCHR(flagbuf, '|')) == (char *) NULL) break;
  226. X            *flagbuf++ = '\0';
  227. X         }
  228. X         Dprintf("(addclass) %s: debugargc = %d\n", classname,
  229. X            classptr->debugargc);
  230. X      }
  231. X   }
  232. X
  233. X   /*
  234. X    * Set all of the class flags.  flag is a bitmap.
  235. X    */
  236. X
  237. X   for (loop = 0; loop < MAXCLASSFLAGS; loop++) {
  238. X      if (flags & (1 << loop))
  239. X         classptr->flags[loop] = 1;
  240. X      else
  241. X         classptr->flags[loop] = 0;
  242. X      Dprintf("(addclass): flags[%d] = %d\n", loop,
  243. X         classptr->flags[loop]);
  244. X   }
  245. X
  246. X   /*
  247. X    * Check to see if we are just overwriting a class description, if so don't
  248. X    * wipe the pointer to the next entry in the list.
  249. X    */
  250. X
  251. X   if (newclass) {
  252. X      classptr->next = classlist;
  253. X      classlist = classptr;
  254. X   }
  255. X
  256. X   Dprintf("(addclass): classlist = %d\n", classlist);
  257. X}
  258. X
  259. X/*************************************************************************/
  260. X/* FUNCTION  : addhost                                                   */
  261. X/* PURPOSE   : Add a host to the list of hosts to transmit to            */
  262. X/* ARGUMENTS : Name of the host, class name, start and stop times        */
  263. X/*************************************************************************/
  264. X
  265. Xvoid
  266. Xaddhost(hostname, classname, times, deltanice, maxload, interval, startint,
  267. X    ttl, ttlpenalty, flags)
  268. X
  269. X   char *hostname, *classname, *times, *flags;
  270. X   int  deltanice, maxload, interval, startint, ttl, ttlpenalty;
  271. X
  272. X{
  273. Xstruct  host    *hostptr,
  274. X                *loopptr,
  275. X                *lastptr = NULL;
  276. Xstruct  class   *classptr;
  277. Xint     loop;
  278. Xchar    *flagbuf;
  279. X
  280. X   if (strlen(hostname) > MAXHOSTNAMELEN - 1) {
  281. X      logerr("(addhost) Host name %s too long, max %d - ignoring\n",
  282. X         classname, MAXHOSTNAMELEN - 1);
  283. X      return;
  284. X   }
  285. X
  286. X   if (strlen(times) > MAXTIMENAMELEN - 1) {
  287. X      logerr("(addhost) Host time %s too long, max %d - ignoring\n",
  288. X         classname, MAXTIMENAMELEN - 1);
  289. X      return;
  290. X   }
  291. X
  292. X   if ((classptr = getclass(classname)) == NULL) {
  293. X      logerr("(addhost) Host's (%s) class %s doesn't exist - ignoring host\n",
  294. X         hostname, classname);
  295. X      return;
  296. X   }
  297. X
  298. X   if (classptr->valid == 0) {
  299. X      logerr("(addhost) Host's (%s) class %s is invalid - ignoring host\n",
  300. X         hostname, classname);
  301. X      return;
  302. X   }
  303. X
  304. X   if (strcmp(classname, "DEFAULT") == 0) {
  305. X      logerr("(addhost) Host (%s) can't be a member of class DEFAULT\n",
  306. X         hostname);
  307. X      return;
  308. X   }
  309. X
  310. X   lastptr = NULL;
  311. X   foreach (hostptr, hostlist) {
  312. X      Dprintf("(addhost): now checking host %s\n", hostptr->hostname);
  313. X      if (strcmp(hostname, hostptr->hostname) == 0) break;
  314. X      lastptr = hostptr;
  315. X   }
  316. X
  317. X   if (hostptr != NULL) {
  318. X      if (hostptr->valid == 1) {
  319. X         logerr("(addhost) Duplicated host %s\n", hostname);
  320. X         return;
  321. X      }
  322. X      if (lastptr != NULL) {
  323. X         lastptr->next = hostptr->next;
  324. X         Dprintf("(addhost) host %s next was %s, now %s\n", lastptr->hostname,
  325. X            hostptr->hostname, hostptr->next ? hostptr->next->hostname : NULL);
  326. X      } else
  327. X         hostlist = hostptr->next;
  328. X   } else {
  329. X      Dprintf("(addhost): CALLOCing new host structure\n");
  330. X      hostptr = (struct host *) calloc(1, sizeof(struct host));
  331. X      if (hostptr == NULL) {
  332. X         logerr("(addhost) Can't calloc struct host for host %s\n",
  333. X            hostname);
  334. X         return;
  335. X      }
  336. X   }
  337. X
  338. X   (void) strcpy(hostptr->hostname, hostname);
  339. X   (void) strcpy(hostptr->class, classname);
  340. X   (void) strcpy(hostptr->times, times);
  341. X   hostptr->valid = 1;
  342. X   hostptr->options.deltanice = deltanice;
  343. X   hostptr->options.maxload = maxload;
  344. X   hostptr->options.interval = interval;
  345. X   hostptr->options.startint = startint;
  346. X   hostptr->options.ttl = ttl;
  347. X   hostptr->options.ttlpenalty = ttlpenalty;
  348. X   hostptr->xmitsernum = 0;
  349. X   hostptr->xargc = 0;
  350. X   classptr->members++;
  351. X
  352. X   if (flags && strlen(flags) > 0) {
  353. X      if ((flagbuf = (char *) calloc(1, strlen(flags) + 1)) != NULL) {
  354. X         (void) strcpy(flagbuf, flags);
  355. X         while (1) {
  356. X            hostptr->xargv[hostptr->xargc++] = flagbuf;
  357. X            if ((flagbuf = STRCHR(flagbuf, '|')) == (char *) NULL) break;
  358. X            *flagbuf++ = '\0';
  359. X         }
  360. X      }
  361. X   }
  362. X
  363. X   for (loop = 0; loop < hostptr->xargc; loop++)
  364. X      Dprintf("host %s: flag[%d] = %s\n", hostname, loop, hostptr->xargv[loop]);
  365. X
  366. X   /*
  367. X    * If this is a new host, do a two-key insertion sort based on the
  368. X    * hostname and name of the transmission class.  Makes things look nice
  369. X    * in the status display...
  370. X    */
  371. X
  372. X   lastptr = NULL;
  373. X
  374. X   if (hostlist == NULL) {
  375. X      Dprintf("(addhost): %s IS hostlist now\n", hostname);
  376. X      hostlist = hostptr;
  377. X   } else {
  378. X      foreach (loopptr, hostlist) {
  379. X         if (((strcmp(hostptr->hostname, loopptr->hostname) < 0) &
  380. X             (strcmp(hostptr->class, loopptr->class) == 0)) | 
  381. X             (strcmp(hostptr->class, loopptr->class) < 0)) {
  382. X            Dprintf("(addhost): Inserting %s before %s\n", hostname,
  383. X               loopptr->hostname);
  384. X            hostptr->next = loopptr;
  385. X            if (lastptr != NULL) lastptr->next = hostptr;
  386. X            if (loopptr == hostlist) hostlist = hostptr;
  387. X            break;
  388. X         }
  389. X         lastptr = loopptr;
  390. X      }
  391. X      if (loopptr == NULL) {
  392. X         Dprintf("(addhost): appending host %s to hostlist\n", hostname);
  393. X         lastptr->next = hostptr; /* append to current host list */
  394. X         hostptr->next = NULL;
  395. X      }
  396. X   }
  397. X   Dprintf("(addhost): hostlist = %d\n", hostlist);
  398. X}
  399. X
  400. X/*************************************************************************/
  401. X/* FUNCTION  : make_invalid                                              */
  402. X/* PURPOSE   : Mark all hosts and classes as invalid                     */
  403. X/* ARGUMENTS : none                                                      */
  404. X/*************************************************************************/
  405. X
  406. Xvoid
  407. Xmake_invalid()
  408. X
  409. X{
  410. Xstruct  class   *classptr,
  411. X                *nextclass;
  412. Xstruct  host    *hostptr,
  413. X                *nexthost;
  414. X
  415. X   dprintf("(make_invalid) marking all classes as invalid\n");
  416. X   for (classptr = classlist; classptr != NULL; classptr = nextclass) {
  417. X      Dprintf("(make_invalid) marking class %s as invalid\n",
  418. X         classptr->classname);
  419. X      classptr->valid = 0;
  420. X      classptr->members = 0;
  421. X      nextclass = classptr->next;
  422. X   }
  423. X
  424. X   dprintf("(make_invalid) marking all hosts as invalid\n");
  425. X   for (hostptr = hostlist; hostptr != NULL; hostptr = nexthost) {
  426. X      Dprintf("(make_invalid) marking host %s as invalid\n", hostptr->hostname);
  427. X      hostptr->valid = 0;
  428. X      nexthost = hostptr->next;
  429. X   }
  430. X
  431. X}
  432. X
  433. X/*************************************************************************/
  434. X/* FUNCTION  : clear_invalid                                             */
  435. X/* PURPOSE   : Remove all hosts and classes which are not valid anymore  */
  436. X/* ARGUMENTS : none                                                      */
  437. X/*************************************************************************/
  438. X
  439. Xvoid
  440. Xclear_invalid()
  441. X
  442. X{
  443. Xstruct  class   *lastclass = NULL,
  444. X                *classptr,
  445. X                *nextclass;
  446. Xstruct  host    *lasthost = NULL,
  447. X                *hostptr,
  448. X                *nexthost;
  449. Xint     loop;
  450. X
  451. X   dprintf("(clear_invalid) clearing all invalid hosts\n");
  452. X   for (hostptr = hostlist; hostptr != NULL; hostptr = nexthost) {
  453. X      nexthost = hostptr->next;
  454. X      if (hostptr->valid == 0) {
  455. X         if (hostptr->pid > 0) {
  456. X            dprintf("(clear_invalid): killing transmitter for host %s\n",
  457. X               hostptr->hostname);
  458. X            if (kill(hostptr->pid, SIGTERM) != 0) xmit_done(-hostptr->pid);
  459. X         }
  460. X         Dprintf("(clear_invalid): clearing host %s\n", hostptr->hostname);
  461. X         if (hostlist == hostptr) hostlist = nexthost;
  462. X         (void) free(hostptr);
  463. X         if (lasthost) lasthost->next = nexthost;
  464. X      } else {
  465. X         lasthost = hostptr;
  466. X      }
  467. X   }
  468. X
  469. X   dprintf("(clear_invalid) clearing all invalid classes\n");
  470. X   for (classptr = classlist; classptr != NULL; classptr = nextclass) {
  471. X      nextclass = classptr->next;
  472. X      if (classptr->valid == 0) {
  473. X         Dprintf("(clear_invalid): clearing class %s\n", classptr->classname);
  474. X         for (loop = 0; loop < classptr->xargc; loop++) {
  475. X            Dprintf("(clear_invalid): clearing class %s argv %d\n",
  476. X               classptr->classname, loop);
  477. X            (void) free(classptr->xargv[loop]);
  478. X         }
  479. X         if (classlist == classptr) classlist = nextclass;
  480. X         (void) free(classptr);
  481. X         if (lastclass) lastclass->next = nextclass;
  482. X      } else {
  483. X         lastclass = classptr;
  484. X      }
  485. X   }
  486. X}
  487. X
  488. X/*************************************************************************/
  489. X/* FUNCTION  : read_config                                               */
  490. X/* PURPOSE   : Read the newsxd configuration file                        */
  491. X/* ARGUMENTS : none                                                      */
  492. X/*************************************************************************/
  493. X
  494. Xvoid
  495. Xread_config(sig)
  496. X   int  sig;
  497. X
  498. X{
  499. XFILE    *config;
  500. X
  501. Xchar    line[MAXPATHLEN],       /* buffer used for inputting lines           */
  502. X        buf[10][MAXPATHLEN],    /* buffers for various command parameters    */
  503. X        *comment;               /* used to trim comments from input lines    */
  504. X
  505. Xint     loop,
  506. X        deltanice,              /* Amount to change proc's nice for xmit     */
  507. X        optioncnt,              /* number of parameters found by sscanf      */
  508. X        maxxmits,               /* number of allowed simul. transmitters     */
  509. X        interval,               /* interval between xmits to a single host   */
  510. X        startint,               /* interval between starting xmits 4 a class */
  511. X        maxload,                /* max allowed load for starting new xmits   */
  512. X        ttl,                    /* maximum time-to-live for a transmitter    */
  513. X        ttlpenalty,             /* time penalty for exceeding ttl            */
  514. X        flags;                  /* option flags for this transmission class  */
  515. X
  516. Xstruct  class   *classptr;      /* used to traverse the class list           */
  517. Xstruct  stat    statbuf;
  518. X
  519. X   if (!(config = fopen(configfile, "r"))) {
  520. X      logerr("Couldn't open config file (%s) - aborting\n", configfile);
  521. X      (void) exit(1);
  522. X   }
  523. X
  524. X   /*
  525. X    * Mark all hosts and classes as undefined, but don't delete 'em yet
  526. X    */
  527. X
  528. X   if (sig) log(LOG_INFO, "reinitializing\n");
  529. X
  530. X   make_invalid();
  531. X
  532. X   CONFIGCHANGED = 1;
  533. X#ifdef FAKESYSLOG
  534. X   CONFIGCHANGEDFILE = 1;
  535. X#endif
  536. X   daemon_idle = 0; /* Allow newsxd to begin running the queue again */
  537. X
  538. X   /*
  539. X    * Reset all of the various data files to their default location
  540. X    */
  541. X
  542. X   (void) strcpy(batchfile, default_batchfile);
  543. X   (void) strcpy(workfile, default_workfile);
  544. X   (void) strcpy(xmitlogs, default_xmitlogs);
  545. X
  546. X   locking  = 0;                /* locking defaults to OFF                */
  547. X   tallying = 0;                /* use of the tally file defaults to OFF  */
  548. X   queueinterval = 60;          /* default queue run interval of 1 minute */
  549. X
  550. X   /*
  551. X    * Add the DEFAULT pseudo-class so that a default xmitter can be specified
  552. X    */
  553. X
  554. X   addclass("DEFAULT", 0, 0, 0, 0, 0, 0, 0, 0, 0);
  555. X
  556. X   while (fgets(line, 255, config) != NULL) {
  557. X
  558. X      if ((comment = index(line, '#')) != NULL)
  559. X         (void) strcpy(comment, "\n");
  560. X
  561. X      Dprintf("> %s", line);
  562. X
  563. X      if (sscanf(line, "tallyfile %s\n", tallyfile) > 0) {
  564. X         dprintf("tallyfile is %s\n", tallyfile);
  565. X         tallying = 1;
  566. X      }
  567. X
  568. X      if (sscanf(line, "batchfile %s\n", batchfile) > 0)
  569. X         dprintf("batchfile is %s\n", batchfile);
  570. X
  571. X      if (sscanf(line, "xmitlogs %s\n", xmitlogs) > 0) {
  572. X         dprintf("xmitlogs is %s\n", xmitlogs); continue; }
  573. X
  574. X      if (sscanf(line, "workfile %s\n", workfile) > 0)
  575. X         dprintf("workfile is %s\n", workfile);
  576. X
  577. X      if (sscanf(line, "queueinterval %d\n", &queueinterval) > 0)
  578. X         dprintf("queueinterval is %d\n", queueinterval);
  579. X
  580. X      if ((optioncnt = sscanf(line, "class %s %s %s %s %s %s %s %s", buf[0],
  581. X         buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8])) > 0) {
  582. X
  583. X         maxxmits = 1;
  584. X         interval = 60;
  585. X         startint = 0;
  586. X         maxload = 99;
  587. X         ttl = 999999;
  588. X         ttlpenalty = 0;
  589. X         flags = 0;
  590. X         deltanice = 0;
  591. X         *buf[9] = '\0';
  592. X
  593. X         Dprintf("optioncnt = %d\n", optioncnt);
  594. X
  595. X         for (loop = 1; loop < optioncnt; loop++) {
  596. X            (void) sscanf(buf[loop], "maxxmits=%d", &maxxmits);
  597. X            (void) sscanf(buf[loop], "maxload=%d", &maxload);
  598. X            (void) sscanf(buf[loop], "nice=%d", &deltanice);
  599. X            (void) sscanf(buf[loop], "interval=%d/%d", &interval, &startint);
  600. X            (void) sscanf(buf[loop], "ttl=%d/%d", &ttl, &ttlpenalty);
  601. X            (void) sscanf(buf[loop], "debug=%s", buf[9]);
  602. X            if (strcmp(buf[loop], "noworkfile") == 0) flags |= (1<<C_NOWORK);
  603. X            if (strcmp(buf[loop], "nobatchfile") == 0) flags |= (1<<C_NOBATCH);
  604. X         }
  605. X
  606. X         dprintf("class %s, maxxmits %d, intvl %d/%d, maxload %d, ttl %d/%d, nice %d, flags=%d, debug=%s\n",
  607. X            buf[0], maxxmits, interval, startint, maxload, ttl, ttlpenalty,
  608. X            deltanice, flags, buf[9]);
  609. X
  610. X         addclass(buf[0], maxxmits, interval, startint, maxload, ttl,
  611. X                  ttlpenalty, deltanice, flags, buf[9]);
  612. X      }
  613. X
  614. X      if ((optioncnt = sscanf(line, "xmit %s %s %s %s %s %s %s %s %s", buf[0],
  615. X         buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8])) > 0) {
  616. X
  617. X         classptr = getclass(buf[0]);
  618. X         if (!classptr | (classptr->valid == 0)) {
  619. X            logerr("(read_config) xmit class for invalid class %s ignored\n",
  620. X               buf[0]);
  621. X         }
  622. X
  623. X         if (stat(buf[1], &statbuf) != 0) {
  624. X            logerr("(read_config) xmit program %s for class %s unavailable\n",
  625. X               buf[1], buf[0]);
  626. X            logerr("(read_config) no xmit for class %s, invalidating class\n",
  627. X               buf[0]);
  628. X            classptr->valid = 0;
  629. X            continue;
  630. X         }
  631. X
  632. X         (void) strcpy(classptr->xpath, buf[1]);
  633. X         for (loop = 2; loop < optioncnt; loop++) {
  634. X            Dprintf("class %s: setting xmit parm %d = %s\n",
  635. X               classptr->classname, loop - 2, buf[loop]);
  636. X            classptr->xargv[loop-2] = (char *) malloc(strlen(buf[loop])+1);
  637. X            (void) strcpy(classptr->xargv[loop-2], buf[loop]);
  638. X         }
  639. X         classptr->xargv[optioncnt - 2] = NULL;
  640. X         classptr->xargc = optioncnt - 2;
  641. X      }
  642. X
  643. X      if ((optioncnt = sscanf(line, "host %s %s %s %s %s %s %s %s", buf[0],
  644. X         buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])) > 0) {
  645. X
  646. X         Dprintf("optioncnt = %d\n", optioncnt);
  647. X
  648. X         interval   = 0;
  649. X         startint   = 0;
  650. X         maxload    = 0;
  651. X         ttl        = 0;
  652. X         ttlpenalty = 0;
  653. X         deltanice  = 0;
  654. X         *buf[9]    = '\0';
  655. X
  656. X         for (loop = 3; loop < optioncnt; loop++) {
  657. X            (void) sscanf(buf[loop], "maxload=%d", &maxload);
  658. X            (void) sscanf(buf[loop], "interval=%d/%d", &interval, &startint);
  659. X            (void) sscanf(buf[loop], "ttl=%d/%d", &ttl, &ttlpenalty);
  660. X            (void) sscanf(buf[loop], "nice=%d", &deltanice);
  661. X            (void) sscanf(buf[loop], "flags=%s", buf[9]);
  662. X         }
  663. X
  664. X         dprintf("host %s, class %s, times %s, deltanice %d, maxload %d, intvl %d/%d, ttl %d/%d, flags=\"%s\"\n",
  665. X               buf[0], buf[1], buf[2], deltanice, maxload, interval, startint,
  666. X               ttl, ttlpenalty, buf[9]);
  667. X
  668. X         addhost(buf[0], buf[1], buf[2], deltanice, maxload, interval, startint,
  669. X               ttl, ttlpenalty, buf[9]);
  670. X      }
  671. X   }
  672. X
  673. X   /*
  674. X    * Remove any hosts or classes not defined anymore
  675. X    */
  676. X
  677. X   clear_invalid();
  678. X
  679. X   (void) fclose(config);
  680. X}
  681. X
  682. X/*************************************************************************/
  683. X/* FUNCTION  : dump_config                                               */
  684. X/* PURPOSE   : Write the current configuration and status of newsxd to   */
  685. X/*             a file                                                    */
  686. X/* ARGUMENTS : none                                                      */
  687. X/*************************************************************************/
  688. X
  689. Xvoid
  690. Xdump_config()
  691. X
  692. X{
  693. Xstruct  host    *hostptr;
  694. Xstruct  class   *classptr;
  695. X
  696. Xchar    lastxmittime[30],          /* bunches of buffers for ctime */
  697. X        buf1[30],
  698. X        buf2[30],
  699. X        pid[30];                /* holds (pid) or "none" */
  700. X
  701. XFILE    *status;
  702. X
  703. Xint    curtime;
  704. X
  705. X   if ((debug <= 0) || (DEBUG <= 0)) {
  706. X      status = fopen(statusfile, "w");
  707. X      if (status == NULL) {
  708. X         logerr("Can't open statusfile (%s, \"w\")\n", statusfile);
  709. X         return;
  710. X      }
  711. X   } else
  712. X      status = stderr;
  713. X
  714. X   curtime = time((long *) NULL);
  715. X   (void) fprintf(status, "%s", ctime(&curtime));
  716. X   if (daemon_idle) (void) fprintf(status, "Newsxd is idled\n");
  717. X
  718. X   if (classlist == NULL) {
  719. X      (void) fprintf(status, "No valid classes defined!\n");
  720. X      return;
  721. X   }
  722. X
  723. X   (void) fputc('\n', status);
  724. X   foreach (classptr, classlist) {
  725. X      if (strcmp(classptr->classname, "DEFAULT") == 0) continue;
  726. X
  727. X      (void) fprintf(status, "Class %-7.7s : %2d active transmitters (%2d max)",
  728. X         classptr->classname, classptr->curxmits, classptr->maxxmits);
  729. X      if (getla() > classptr->options.maxload)
  730. X         (void) fprintf(status, " [no new xmits, load %d > %d max]",
  731. X            getla(), classptr->options.maxload);
  732. X      (void) fputc('\n', status);
  733. X   }
  734. X
  735. X   (void) fputc('\n', status);
  736. X   (void) fprintf(status, "                         Service   Valid Start   Last XMIT  Xmitter  Why Not\n");
  737. X   (void) fprintf(status, "Hostname                  Class       Times       Started     pid    Running\n");
  738. X   (void) fprintf(status, "-----------------------  -------  -------------  ---------  -------  ----------\n");
  739. X
  740. X   if (hostlist == NULL) {
  741. X      (void) fprintf(status, "No valid hosts defined!\n");
  742. X   }
  743. X
  744. X   foreach (hostptr, hostlist) {
  745. X      if (hostptr->lasttime == NULL)
  746. X         (void) strcpy(lastxmittime, "* NEVER *");
  747. X      else {
  748. X         (void) sscanf(ctime(&hostptr->lasttime), "%s %*s %*s %s", buf1, buf2);
  749. X         (void) sprintf(lastxmittime, "%s %5.5s", buf1, buf2);
  750. X      }
  751. X
  752. X      (void) sprintf(pid, (hostptr->pid) ? "%d" : "none", hostptr->pid);
  753. X
  754. X      (void) fprintf(status, "%-23.23s  %-7s  %-13.13s  %9s   %5s   ",
  755. X         hostptr->hostname, hostptr->class, hostptr->times, lastxmittime, pid);
  756. X
  757. X      if (daemon_idle && hostptr->whynot != WN_RUNNING)
  758. X         (void) fputs("newsxd Idl", status);
  759. X      else
  760. X         (void) fputs(wnlist[hostptr->whynot], status);
  761. X      (void) fputc('\n', status);
  762. X   }
  763. X   if ((debug <= 0) || (DEBUG <= 0)) (void) fclose(status);
  764. X}
  765. X
  766. X/*************************************************************************/
  767. X/* FUNCTION  : dump_info                                                 */
  768. X/* PURPOSE   : Dump newsxd's data structures to a file.                  */
  769. X/* ARGUMENTS : none                                                      */
  770. X/*************************************************************************/
  771. X
  772. Xvoid
  773. Xdump_info()
  774. X
  775. X{
  776. Xstruct  host    *hostptr;
  777. Xstruct    class    *classptr;
  778. X
  779. Xlong    curtime;
  780. X
  781. Xint    loop, which;
  782. X
  783. XFILE    *status;
  784. X
  785. Xchar    outfile[MAXPATHLEN];
  786. X
  787. X   if ((debug <= 0) || (DEBUG <= 0)) {
  788. X      (void) sprintf(outfile, "%s.dump", statusfile);
  789. X      status = fopen(outfile, "w");
  790. X      if (status == NULL) {
  791. X         logerr("Can't open statusfile (%s, \"w\")\n", statusfile);
  792. X         return;
  793. X      }
  794. X   } else
  795. X      status = stderr;
  796. X
  797. X   curtime = time((long *) NULL);
  798. X
  799. X   (void) fprintf(status, "Newsxd data structures at %s\n", ctime(&curtime));
  800. X
  801. X   (void) fprintf(status, "debug is %s, DEBUG is %s, newsxdebug is %s\n",
  802. X      debug ? "On" : "Off", DEBUG ? "On" : "Off", newsxdebug ? "On" : "Off");
  803. X
  804. X   (void) fprintf(status, "Queue runs occur every %d seconds, newsxd %s idled\n\n",
  805. X      queueinterval, daemon_idle ? "IS" : "is not");
  806. X
  807. X   (void) fprintf(status, "Active transmitter PID mappings:\n");
  808. X
  809. X   which = 0;
  810. X   for (loop = 0; loop < MAXXMITTERS; loop++) {
  811. X      if (pidlist[loop] != 0) {
  812. X         if (!which) (void) fputc('\n', status);
  813. X         (void) fprintf(status, "pid %5d --> %-25.25s ", pidlist[loop],
  814. X            pidmap[loop]->hostname);
  815. X         which = !which;
  816. X      }
  817. X   }
  818. X
  819. X   (void) fputs("\n\n", status);
  820. X
  821. X   (void) fprintf(status, "batchfile is                 %s\n", batchfile);
  822. X   (void) fprintf(status, "workfile is                  %s\n", workfile);
  823. X   (void) fprintf(status, "xmitlogs is                  %s\n", xmitlogs);
  824. X   (void) fprintf(status, "newsxd status written to     %s\n", statusfile);
  825. X   (void) fprintf(status, "newsxd pid written to        %s\n", pidfile);
  826. X   (void) fprintf(status, "newsxd config file is        %s\n", configfile);
  827. X   (void) fprintf(status, "\n");
  828. X
  829. X   if (classlist == NULL) (void) fprintf(status, "NO DEFINED CLASSES\n");
  830. X
  831. X   foreach (classptr, classlist) {
  832. X      (void) fprintf(status, "CLASS %s (%02d members)\n\n", classptr->classname,
  833. X         classptr->members);
  834. X      (void) fprintf(status, "     xmit prog  %s", classptr->xpath);
  835. X      for (loop = 0; loop < classptr->xargc; loop++)
  836. X         (void) fprintf(status, " %s", classptr->xargv[loop]);
  837. X      (void) fprintf(status, "\n");
  838. X      (void) fprintf(status, "     xmitters   %02d running, %02d max\n",
  839. X         classptr->curxmits, classptr->maxxmits);
  840. X      (void) fprintf(status, "     last xmit  %s", ctime(&classptr->laststart));
  841. X      (void) fprintf(status, "     sernum     %d\n", classptr->xmitsernum);
  842. X
  843. X      (void) fprintf(status, "     options   ");
  844. X      if (classptr->options.deltanice)
  845. X         (void) fprintf(status, " nice=%d", classptr->options.deltanice);
  846. X      if (classptr->options.interval)
  847. X         (void) fprintf(status, " interval=%d", classptr->options.interval);
  848. X      if (classptr->options.startint)
  849. X         (void) fprintf(status, " startint=%d", classptr->options.startint);
  850. X      if (classptr->options.ttl)
  851. X         (void) fprintf(status, " ttl=%d", classptr->options.ttl);
  852. X      if (classptr->options.ttlpenalty)
  853. X         (void) fprintf(status, " ttlpenalty=%d", classptr->options.ttlpenalty);
  854. X      if (classptr->options.maxload)
  855. X         (void) fprintf(status, " maxload=%d", classptr->options.maxload);
  856. X
  857. X      (void) fputc('\n', status);
  858. X      (void) fprintf(status, "     slots      ");
  859. X      for (loop = 0; loop < MAXCLASSXMITTERS; loop++) {
  860. X         if ((loop > 0) & ((loop % 50) == 0))
  861. X            (void) fputs("\n                ", status);
  862. X         (void) fputc(classptr->slots[loop], status);
  863. X      }
  864. X
  865. X      (void) fputs("\n\n", status);
  866. X   }
  867. X
  868. X   if (hostlist == NULL) (void) fprintf(status, "NO DEFINED HOSTS\n");
  869. X
  870. X   foreach (hostptr, hostlist) {
  871. X      (void) fprintf(status, "HOST %s\n", hostptr->hostname);
  872. X
  873. X      (void) fprintf(status, "     class      %s\n", hostptr->class);
  874. X      (void) fprintf(status, "     xmit times %s\n", hostptr->times);
  875. X      (void) fprintf(status, "     xmit pid   %d\n", hostptr->pid);
  876. X      (void) fprintf(status, "     last xmit  %s", hostptr->lasttime ? 
  877. X         ctime(&hostptr->lasttime) : "NEVER\n");
  878. X      (void) fprintf(status, "     penalty to %s", hostptr->penaltytime ?
  879. X         ctime(&hostptr->penaltytime) : "NONE\n");
  880. X      (void) fprintf(status, "     xmitsernum %d\n", hostptr->xmitsernum);
  881. X      (void) fprintf(status, "     whynot     %s (%d)\n", 
  882. X         wnlist[hostptr->whynot], hostptr->whynot);
  883. X      (void) fprintf(status, "     xmit slot  %d\n", hostptr->classslot);
  884. X      (void) fprintf(status, "     xmit flags");
  885. X
  886. X      for (loop = 0; loop < hostptr->xargc; loop++)
  887. X         (void) fprintf(status, " %s", hostptr->xargv[loop]);
  888. X
  889. X      (void) fputc('\n', status);
  890. X      (void) fprintf(status, "     options   ");
  891. X      if (hostptr->options.deltanice)
  892. X         (void) fprintf(status, " nice=%d", hostptr->options.deltanice);
  893. X      if (hostptr->options.interval)
  894. X         (void) fprintf(status, " interval=%d", hostptr->options.interval);
  895. X      if (hostptr->options.startint)
  896. X         (void) fprintf(status, " startint=%d", hostptr->options.startint);
  897. X      if (hostptr->options.ttl)
  898. X         (void) fprintf(status, " ttl=%d", hostptr->options.ttl);
  899. X      if (hostptr->options.ttlpenalty)
  900. X         (void) fprintf(status, " ttlpenalty=%d", hostptr->options.ttlpenalty);
  901. X      if (hostptr->options.maxload)
  902. X         (void) fprintf(status, " maxload=%d", hostptr->options.maxload);
  903. X
  904. X      (void) fputs("\n\n", status);
  905. X   }
  906. X
  907. X   if ((debug <= 0) || (DEBUG <= 0)) (void) fclose(status);
  908. X}
  909. END_OF_FILE
  910.   if test 28527 -ne `wc -c <'config.c'`; then
  911.     echo shar: \"'config.c'\" unpacked with wrong size!
  912.   fi
  913.   # end of 'config.c'
  914. fi
  915. if test -f 'newsxd.8' -a "${1}" != "-c" ; then 
  916.   echo shar: Will not clobber existing file \"'newsxd.8'\"
  917. else
  918.   echo shar: Extracting \"'newsxd.8'\" \(17954 characters\)
  919.   sed "s/^X//" >'newsxd.8' <<'END_OF_FILE'
  920. X.TH newsxd 8
  921. X.SH NAME
  922. Xnewsxd \- daemon for managing the transmission of news
  923. X.SH SYNTAX
  924. X.B newsxd
  925. X[\-debug] [\-DEBUG] [\-newsxdebug] [\-c \fIfile\fR] [\-v]
  926. X[\-pid \fIfile\fR\|] [\-status \fIfile\fR] [\-log \fIfile\fR]
  927. X.br
  928. X.SH DESCRIPTION
  929. XThe
  930. X.I newsxd
  931. Xprogram
  932. Xis a configurable daemon for controlling the transmission
  933. Xof netnews.  It allows the definition of multiple categories of service,
  934. Xby setting a number of parameters defining things such as how often news is to
  935. Xbe transmitted, the number of news transmitters that can be active at one
  936. Xtime, the maximum time a transmitter may spend sending netnews to a single
  937. Xhost, and the maximum system load at which netnews transmitters may be
  938. Xstarted.
  939. X.I newsxd
  940. Xcan also be used to start up other programs which must be restarted
  941. Xupon exit, or which must be run at regular intervals with greater granularity
  942. Xthan
  943. X.I cron(8)
  944. Xallows.
  945. X.PP
  946. XWhen starting up, the
  947. X.I newsxd
  948. Xprogram reads a configuration file
  949. X(usually \fI/usr/local/etc/newsxd.conf\fR) which specifies all of the
  950. Xclasses of service and their characteristics, where certain data files
  951. Xare to be stored and what hosts netnews is to be transmitted to.
  952. X.PP
  953. X.I newsxd
  954. Xis a daemon, and while it replaces such programs as
  955. X.I nntpsend,
  956. Xit is not meant to be run from
  957. X.I cron(8),
  958. Xbut rather from /etc/rc.local.  If you have multiple copies of
  959. X.I newsxd
  960. Xrunning the results will be unpredictable.
  961. X.SH OPTIONS
  962. X.IP -debug 15
  963. XEnables debugging.  If debugging is enabled,
  964. X.I newsxd
  965. Xwill not switch to daemon mode (i.e. will not detach itself from the
  966. Xcontrolling terminal).
  967. X.IP -DEBUG
  968. XEnables painfully verbose debugging.
  969. X.IP -newsxdebug
  970. XEnables debugging when running
  971. X.I nntpxmit.
  972. XAlso causes
  973. X.I nntpxmit
  974. Xto be run synchronously
  975. X.I (newsxd
  976. Xwill wait for the
  977. X.I nntpxmit
  978. Xto complete before continuing with other hosts).
  979. X.IP "-c \fIfile\fR"
  980. XSpecifies an alternate configuration file for
  981. X.I newsxd
  982. Xto load.
  983. X.IP "-pid \fIfile\fR"
  984. XSpecifies an alternate file for
  985. X.I newsxd
  986. Xto write its PID into when starting up.
  987. X.IP "-status \fIfile\fR"
  988. XSpecifies an alternate file for
  989. X.I newsxd
  990. Xto write its status into upon receipt of a QUIT signal.
  991. X.IP "-log \fIfile\fR"
  992. XSpecifies an alternate file for
  993. X.I newsxd
  994. Xto write its logging information into when FAKESYSLOG is being used.
  995. X.IP "-v"
  996. XDisplays the version of newsxd that you are running.  \fINewsxd\fR
  997. Xdoes NOT start running if the -v switch is specified.
  998. X.RE
  999. X.PP
  1000. XThe configuration file for
  1001. X.I newsxd
  1002. Xconsists of commands from the list below.  Comments are preceded by
  1003. Xpound (\#) signs and continue to the end of the line.  Case is significant.
  1004. X.PP
  1005. X
  1006. Xclass \fItype [options]\fR
  1007. X
  1008. Xdefines a class of service.  \fItype\fR can be any printable string less than
  1009. Xeight characters long (0, 5, 9, high, low, boring, etc.)  There are a number
  1010. Xof options that can be specified (as a space-separated list) that will modify
  1011. Xthe behavior of a service class:
  1012. X.RS +.5i
  1013. X.IP maxxmits=\fIn\fR 15
  1014. Xspecifies the maximum number of netnews transmitters that
  1015. X.I newsxd
  1016. Xwill allow to be running simultaneously for this service class.  The
  1017. Xdefault value is 1.
  1018. X.IP interval=\fIn[/m]\fR
  1019. Xspecifies the start-to-start interval (in seconds) between successive
  1020. Xinvocations of a netnews transmitter for a single host.  The default value
  1021. Xis 60 seconds.  The optional parameter \fIm\fR specifies the number of
  1022. Xseconds to wait between starting new transmitters for ANY host in this
  1023. Xservice class; this is useful to prevent many transmitters from being
  1024. Xstarted simultaneously and spiking the system load.  The intra-class
  1025. Xstartup interval, \fIm\fR, should not divide the \fIqueueinterval\fR
  1026. X(below) evenly.
  1027. X.IP maxload=\fIn\fR
  1028. Xdefines the maximum load at which
  1029. X.I newsxd
  1030. Xwill start transmitters for this service class.  If the load passes beyond
  1031. Xthis value, no new transmitters will be started until the load drops.  Any
  1032. Xcurrently running transmitters will not be affected.
  1033. X.IP ttl=\fIn[/m]\fR
  1034. Xgives the maximum time-to-live in seconds for any invocation of a netnews
  1035. Xtransmitter.  The default value is 999999 seconds (about 11 days).  The
  1036. Xoptional parameter, \fIm\fR, gives the number of seconds to penalize a
  1037. Xtransmitter that has exceeded its ttl; this is the number of seconds to
  1038. Xprevent a new transmitter from starting up for the penalized host.
  1039. X.IP noworkfile
  1040. XNormally the article batch file for the host is renamed before executing
  1041. Xthe netnews transmitter as defined by the \fIworkfile\fR below.  This option
  1042. Xcauses the renaming to be bypassed.
  1043. X.IP nobatchfile
  1044. XNormally an article batch file must exist for the host before
  1045. X.I newsxd
  1046. Xwill execute the transmitter for the host.  If this option is defined,
  1047. Xthe check for a batch file will be bypassed.
  1048. X.RE
  1049. X.IN -5
  1050. X.PP
  1051. X
  1052. Xxmit \fIclassname programpath programname [parameters]\fR
  1053. X
  1054. Xdefines an alternate netnews transmission program, for which command-line
  1055. Xoptions can be specified.  You *MUST* define a transmission program for the
  1056. Xclass
  1057. X.I DEFAULT,
  1058. Xwhich will be used as the default news transmitter for all other classes.
  1059. XSee the example configuration shown below.  \fINewsxd\fR will use the
  1060. Xenvironment variable PATH that it was invoked with to search for the program
  1061. Xif an explicit path is not given.
  1062. X.RS +.5i
  1063. X.IP classname 15
  1064. Xis the name of an already-defined service class which is to
  1065. Xuse this transmission program.
  1066. X.IP programpath
  1067. Xis the path of the file to execute
  1068. X.IP programname
  1069. Xis the name to be passed to the program as argv[0];
  1070. Xusually the last component of \fIprogrampath\fR.
  1071. X.IP [parameters]
  1072. Xoptional parameters and options (up to nine) to be
  1073. Xpassed to the news transmitter.  In
  1074. X.I parameters,
  1075. Xthe following conversions will be made:
  1076. X.RS 15
  1077. X.IP %f 5
  1078. Xwill be replaced with the per-host flags specified by the
  1079. X.I host
  1080. Xcommand (see below).
  1081. X.IP %h
  1082. Xwill be replaced with the host name.
  1083. X.IP %w
  1084. Xwill be replaced with the name of the workfile for the host.
  1085. X.IP %b
  1086. Xwill be replaced with the name of the batchfile for the host.
  1087. X.IP %s
  1088. Xwill be replaced by an integer which is unique to all of the active
  1089. Xtransmitters for that class.  Newsxd will select the lowest unused integer
  1090. Xeach time a transmitter is started.  These 'slot numbers' start at 0.
  1091. X.RE
  1092. X.RE
  1093. X.PP
  1094. X
  1095. Xqueueinterval \fIseconds\fR
  1096. X
  1097. Xspecifies the number of seconds between "queue runs".  During each queue
  1098. Xrun
  1099. X.I newsxd
  1100. Xwill check each host to see if a netnews transmitter can be started for
  1101. Xthat host.  The queueinterval should be at least as small as the smallest
  1102. Xinterval specified in all of the \fIclass\fR definitions.  The default value
  1103. Xfor \fIqueueinterval\fR is 60 seconds.
  1104. X.PP
  1105. X
  1106. Xbatchfile \fIfile\fR
  1107. X
  1108. Xspecifies the file path where the batch files (files listing article paths
  1109. Xor IDs to be used by a netnews transmitter) are stored.  A %s in \fIfile\fR
  1110. Xwill be replaced by the name of the current host.  Unless the
  1111. X.I nobatchfile
  1112. Xoption was specified for the host's service class, this
  1113. Xfile must exist before a netnews transmitter will be executed for the host.
  1114. XThe default value for \fIbatchfile\fR is defined in newsxd.h and is normally
  1115. X\fI/usr/spool/batch/%s\fR.
  1116. X.PP
  1117. X
  1118. Xworkfile \fIfile\fR
  1119. X
  1120. Xspecifies the file path which the batch files are to be renamed to before
  1121. Xexecuting the netnews transmitter.  A %s in \fIfile\fR will be replaced by
  1122. Xthe name of the current host.  If the \fInoworkfile\fR option was specified
  1123. Xfor this host's service class, the batch file will NOT be renamed.  The
  1124. Xdefault value for \fIworkfile\fR is defined in newsxd.h and is normally
  1125. X\fI/usr/spool/batch/%s.work\fR.
  1126. X.PP
  1127. X
  1128. Xxmitlogs \fIfile\fR
  1129. X
  1130. Xwhere to log the output of each netnews transmitter.  If you need to keep
  1131. Xthe information printed by a transmitter, use this option.  If you don't
  1132. Xneed to use up the disk space, leave \fIxmitlogs\fR undefined and output
  1133. Xwill be sent to /dev/null.
  1134. X.PP
  1135. X
  1136. Xhost \fIhostname classname xmittimes [options]\fR
  1137. X
  1138. Xdefines a host which to which
  1139. X.I newsxd
  1140. Xwill transmit netnews.
  1141. X.RS +.5i
  1142. X.IP hostname 15
  1143. XThe name of the host to pass to the netnews transmitter.
  1144. X.IP classname
  1145. XThe name of the service class that this host is in.
  1146. X.IP xmittimes
  1147. XThe time(s) to allow new transmitters to start for this host.  See the
  1148. Xmanpage for
  1149. X.I L.sys(5)
  1150. Xfor the format of
  1151. X.I xmittimes.
  1152. X.IP [options]
  1153. XThere are some options which can be used to modify the behavior of the
  1154. Xnetnews transmitter for a host:
  1155. X.RS +.5i
  1156. X.IP nice=\fIn\fR 15
  1157. XThis optional value is added to the \fInice(3)\fR of the netnews
  1158. Xtransmitter.  To be able to run at higher priorities (a lower \fInice\fR
  1159. Xvalue),
  1160. X.I newsxd
  1161. Xmust be
  1162. X.I setuid(3)
  1163. Xroot; otherwise
  1164. X.I newsxd
  1165. Xshould be
  1166. X.I setuid(3)
  1167. Xnews.  If no
  1168. X\fIdeltanice\fR value is specified, the nice of the transmitter is not
  1169. Xmodified by
  1170. X.I newsxd.
  1171. X.IP flags=\fIn\fR 15
  1172. XUsed to specify optional flags to be passed to the netnews transmitter for
  1173. Xthe host.  The flags must be separated by vertical bars (|), not spaces,
  1174. Xin the 
  1175. X.I newsxd.conf
  1176. Xfile.  Note that "-l something" would be TWO flags and you would say
  1177. Xflags=-l|something.
  1178. X.I Newsxd
  1179. Xwill automatically separate the flags before calling the netnews
  1180. Xtransmitter.
  1181. XXXX
  1182. X.IP ttl=\fIn[/m]\fR
  1183. XThe \fIttl\fR option may be used to override the default value established 
  1184. Xby the \fIclass\fR command (described above).
  1185. X.IP interval=\fIn[/m]\fR
  1186. XThe \fIinterval\fR option may be used to override the default value established 
  1187. Xby the \fIclass\fR command (described above).
  1188. X.IP maxload=\fIn\fR
  1189. XThe \fImaxload\fR option may be used to override the default value established 
  1190. Xby the \fIclass\fR command (described above).
  1191. X.IP maxxmits=\fIn\fR
  1192. XThe \fImaxxmits\fR option may be used to override the default value established 
  1193. Xby the \fIclass\fR command (described above).
  1194. X.RE
  1195. X.IN -5
  1196. X.PP
  1197. X.SH "SIMPLE EXAMPLE"
  1198. XThe following is an example of a simple configuration file:
  1199. X
  1200. X.nf
  1201. X.ft CW
  1202. X# Define a service class that just runs an nntpxmit to each host
  1203. X# every hour.  Don't run nntpxmit if the load goes over 8.
  1204. X
  1205. Xclass   normal  maxxmits=1  interval=3600  maxload=8
  1206. X
  1207. X# Define the default news transmitter
  1208. Xxmit    DEFAULT /usr/local/lib/news/nntpxmit nntpxmit %h:%w
  1209. X
  1210. X# Check the list of hosts every 10 minutes to see if we can send news to
  1211. X# someone yet.
  1212. Xqueueinterval    600
  1213. X
  1214. X# In all of the following options, %s is replaced by the host name of the
  1215. X# system being sent to.
  1216. X
  1217. X# File news places articles paths/ids in
  1218. Xbatchfile   /usr/spool/batch/%s
  1219. X
  1220. X# File a news transmitter wants articles paths/ids in
  1221. Xworkfile    /usr/spool/batch/%s.work
  1222. X
  1223. X# Hosts to send news to.  Each line is of the format:
  1224. X#                            CLASS   VALID START
  1225. X# host HOSTNAME              NAME       TIMES
  1226. X
  1227. Xhost dorothy                 normal  Any
  1228. Xhost toto                    normal  Any
  1229. Xhost wizard                  normal  Any
  1230. Xhost witch                   normal  Any
  1231. Xhost tinman                  normal  Any
  1232. Xhost lion                    normal  Any
  1233. X.ft P
  1234. X.fi
  1235. X.PP
  1236. X.RE
  1237. X.LP
  1238. X.SH "COMPLEX EXAMPLE"
  1239. XThe following is an example of a more complex configuration file that
  1240. Xuses most of the options supported by
  1241. X.I newsxd:
  1242. X
  1243. X.nf
  1244. X.ft CW
  1245. X# Define a series of service classes for sending news to other sites:
  1246. X#     nlink     NNTPlink Transmits (Continuous NNTPXMITs)
  1247. X#     high      High Priority Transmits (Top-40)
  1248. X#     med       Medium Prio Transmits (Non Top-40)
  1249. X#     low       Low Priority Transmits (Endnodes)
  1250. X#     batch     Batched (with sendbatch) newsfeeds
  1251. X
  1252. Xclass   nlink   maxxmits=20 interval=60    maxload=10  noworkfile
  1253. Xxmit    nlink   /usr/local/lib/news/nntplink nntplink %h:%b
  1254. X
  1255. Xclass   high    maxxmits=99 interval=60/20 maxload=8   ttl=1800
  1256. X
  1257. Xclass   med     maxxmits=5  interval=300   maxload=6   ttl=1800/60
  1258. X
  1259. Xclass   low     maxxmits=3  interval=1200  maxload=5   ttl=1100/60
  1260. X
  1261. Xclass   batch   maxxmits=1  interval=3600  maxload=5   ttl=1800/1800
  1262. Xxmit    batch   /usr/local/lib/news/sendbatch sendbatch %f %h
  1263. X
  1264. X# Define the default news transmitter
  1265. Xxmit    DEFAULT /usr/local/lib/news/nntpxmit nntpxmit %h:%w
  1266. X
  1267. X# Check the transmit queue every <n> seconds (this should be at least as
  1268. X# low as the smallest "interval" in all of the transmission classes).
  1269. Xqueueinterval    20
  1270. X
  1271. X# In all of the following options, %s is replaced by the host name of the
  1272. X# system being sent to.
  1273. X
  1274. X# File news places articles paths/ids in
  1275. Xbatchfile   /usr/spool/batch/%s
  1276. X
  1277. X# File a news transmitter wants articles paths/ids in
  1278. Xworkfile    /usr/spool/batch/%s.work
  1279. X
  1280. X# Where to log the output of a news transmitter (default is /dev/null)
  1281. X# xmitlogs   /usr/spool/batch/%s.log
  1282. X
  1283. X# Hosts to send news to.  Each line is of the format:
  1284. X#                            CLASS   VALID START
  1285. X# host HOSTNAME              NAME       TIMES          OPTIONS
  1286. X
  1287. Xhost dorothy                 low     Any               nice=10
  1288. Xhost toto                    low     Any               nice=10
  1289. Xhost wizard                  low     Any               nice=10
  1290. Xhost witch                   low     Any               nice=10
  1291. Xhost tinman                  low     Any               nice=10
  1292. Xhost lion                    low     Any               nice=10
  1293. Xhost cactus.biz.com          low     Any               nice=10
  1294. Xhost endnode.foobar.edu      low     Any2000-0500      nice=10
  1295. Xhost biggernode.foobar.edu   med     SaSu|Wk1730-0730
  1296. Xhost bignode.company.com     med     Any             
  1297. Xhost midsize.company.com     med     Any             
  1298. Xhost university.podunk.edu   med     Any             
  1299. Xhost mrbackbone.bigu.edu     high    Any             
  1300. Xhost gateway.bizness.com     high    Any             
  1301. Xhost supernews.hellou.edu    high    Any             
  1302. Xhost mrnntp.aloha.edu        high    Any             
  1303. Xhost hello.world.edu         high    Any             
  1304. Xhost supernews.foou.edu      nlink   Any
  1305. Xhost backbone.newssite.edu   nlink   Any
  1306. Xhost fred                    batch   Any nice=20 flags=-s500000 interval=86400
  1307. Xhost barney                  batch   Any nice=20 flags=-s250000 interval=86400
  1308. Xhost wilma                   batch   Any nice=20 flags=-s500000
  1309. Xhost betty                   batch   Any nice=20 flags=-s500000|-m500000
  1310. Xhost kitty                   batch   SaSu|Wk1730-730 flags=-c|-s250000
  1311. Xhost dino                    batch   SaSu|Wk1730-730 flags=-c|-s250000
  1312. Xhost bambam                  batch   Sa interval=86400
  1313. X
  1314. X# Notes: Only send news to biggernode.foobar.edu during non-business hours
  1315. X#        endnode.foobar.edu only wants news transmitted from 8PM to 5AM.
  1316. X#        Only send news to fred and barney once per day (every 24 hours).
  1317. X#        Do one batching run for bambam each Saturday.
  1318. X.ft P
  1319. X.fi
  1320. X.PP
  1321. X.RE
  1322. X.LP
  1323. X.SH "CONTROLLING NEWSXD"
  1324. XThe following signals have the specified effect when sent to the
  1325. Xserver
  1326. X.I named
  1327. Xprocess using the
  1328. X.I kill
  1329. Xcommand:
  1330. X.IP SIGHUP 13
  1331. XCauses newsxd to reload newsxd.conf and remove (kill) any hosts or
  1332. Xtransmitters which are no longer defined.
  1333. X.IP SIGTERM
  1334. XCauses newsxd to shut down, killing all active transmitters
  1335. X.IP SIGQUIT
  1336. XDumps the current newsxd status to
  1337. X.I /usr/tmp/newsxd.status
  1338. X.IP SIGIOT
  1339. XCauses newsxd to kill all active transmitters and go into idle mode.
  1340. XSend a HUP signal to newsxd to return to normal operating mode.
  1341. X.IP SIGIO
  1342. XCauses newsxd to go into idle mode, where no new transmitters are started.
  1343. XSend a HUP signal to newsxd to return to normal operating mode.
  1344. X.IP SIGTRAP
  1345. XCauses newsxd to write a DETAILED list of the contents of all important
  1346. Xinternal data structures to
  1347. X.I /usr/tmp/newsxd.status.dump
  1348. X.IP SIGUSR1
  1349. XIncreases the current debugging level.  Caution: the debugging information
  1350. Xcan get very voluminous, especially if DEBUG is enabled.
  1351. X.IP SIGUSR2
  1352. XDecreases the current debugging level.
  1353. X.SH "THE STATUS FILE"
  1354. XThe
  1355. X.I newsxd.status
  1356. Xfile, which is created when a SIGQUIT signal is sent to 
  1357. X.I newsxd,
  1358. Xshows the current state of all of the hosts managed by
  1359. X.I newsxd.
  1360. XThere are several pieces of information listed for each host,
  1361. Xincluding the host name, the times during which a new netnews transmitter
  1362. Xcan be started, the last time a netnews transmitter was started, and a
  1363. X"Why Not Running" field which indicates why a netnews transmitter is not
  1364. Xcurrently running for that host.  The various types of "Why Not Running"
  1365. Xmessages include:
  1366. X
  1367. X.IP "TTL Penlty" 15
  1368. XThe netnews transmitter for the host ran longer than the time-to-live
  1369. Xdefined for the service class, and the host is currently being penalized.
  1370. X.IP "TTL Kill"
  1371. XThe netnews transmitter for the host was just killed because it ran
  1372. Xlonger than the time-to-live defined for the service class.
  1373. X.IP "Class Intv"
  1374. XNo new transmitters in this service class can start up yet because the
  1375. Xintra-class transmitter startup interval hasn't passed.  See the
  1376. X.I interval
  1377. Xoption under
  1378. X.I class,
  1379. Xabove.
  1380. X.IP "Host Intvl"
  1381. XNo new transmitters for this host can start up yet because a transmitter
  1382. Xhas already been run for this host recently (see the 
  1383. X.I interval
  1384. Xoption under
  1385. X.I class,
  1386. Xabove).
  1387. X.IP "High Load"
  1388. XThe system load is too high to start new netnews transmitters for this
  1389. Xservice class.  See the
  1390. X.I maxload
  1391. Xoption under
  1392. X.I class,
  1393. Xabove.
  1394. X.IP "Wrong Time"
  1395. XThe current time doesn't fit any of the allowed startup times specified
  1396. Xfor the host.
  1397. X.IP "Max Xmits"
  1398. XThe maximum number of netnews transmitters for this class are already
  1399. Xrunning.  See the
  1400. X.I maxxmits
  1401. Xoption under
  1402. X.I class,
  1403. Xabove.
  1404. X.IP "RUNNING"
  1405. XA netnews transmitter for this host is currently running.
  1406. X.IP "No Work"
  1407. XThere are currently no articles to send to this host.
  1408. X.IP "Bad Rename"
  1409. X.I newsxd
  1410. Xcouldn't rename the host's
  1411. X.I batchfile
  1412. Xto the
  1413. X.I workfile.
  1414. X.IP "NotMyTurn"
  1415. XThe host has already had a chance to transmit news and now it's time for
  1416. Xthe other hosts to get a chance.  
  1417. X.I Newsxd
  1418. Xuses a round-robin scheduling algorithm to insure the fair transmission
  1419. Xof netnews.
  1420. X
  1421. X.SH RESTRICTIONS
  1422. XDoes not do exponential backoff when the transmitter for a host fails.
  1423. X.SH BUGS
  1424. XNo known bugs exist in
  1425. X.I newsxd,
  1426. Xbut the wish list of features to add is quite long...
  1427. X.SH FILES
  1428. X.IP /usr/local/etc/newsxd.conf 28
  1429. X.I newsxd
  1430. Xconfiguration file
  1431. X.IP /usr/tmp/newsxd.pid 
  1432. XProcess ID number
  1433. X.IP /usr/tmp/newsxd.status 
  1434. XDump of
  1435. X.I newsxd
  1436. Xstatus
  1437. X.IP /usr/spool/batch/*
  1438. Xbatch and work files for
  1439. X.I newsxd
  1440. Xand netnews transmitters.
  1441. X.SH "SEE ALSO"
  1442. Xnntpxmit(1)
  1443. X.SH AUTHOR
  1444. XChris Myers <chris@wugate.wustl.edu>
  1445. END_OF_FILE
  1446.   if test 17954 -ne `wc -c <'newsxd.8'`; then
  1447.     echo shar: \"'newsxd.8'\" unpacked with wrong size!
  1448.   fi
  1449.   # end of 'newsxd.8'
  1450. fi
  1451. echo shar: End of archive 1 \(of 3\).
  1452. cp /dev/null ark1isdone
  1453. MISSING=""
  1454. for I in 1 2 3 ; do
  1455.     if test ! -f ark${I}isdone ; then
  1456.     MISSING="${MISSING} ${I}"
  1457.     fi
  1458. done
  1459. if test "${MISSING}" = "" ; then
  1460.     echo You have unpacked all 3 archives.
  1461.     rm -f ark[1-9]isdone
  1462. else
  1463.     echo You still must unpack the following archives:
  1464.     echo "        " ${MISSING}
  1465. fi
  1466. exit 0
  1467. exit 0 # Just in case...
  1468.